<template>
  <el-dialog
    title="上传举报视频"
    :close-on-click-modal="false"
    :visible.sync="visible">
    <el-form :model="dataForm"  ref="dataForm" @keyup.enter.native="dataFormSubmit()" label-width="80px">
     <div id="global-uploader">
        <!-- 上传 -->
        <uploader
                ref="uploader"
                :options="options"
                :autoStart="false"
                @file-added="onFileAdded"
                @file-success="onFileSuccess"
                @file-progress="onFileProgress"
                @file-error="onFileError"
                @file-removed="fileRemoved"
                :file-status-text="statusText"
                class="uploader-app">
   <div >
          <uploader-btn id="global-uploader-btn" :attrs="attrs" single  ref="uploadBtn">选择文件</uploader-btn>
          <uploader-list v-show="panelShow">
                <div class="file-panel" slot-scope="props" :class="{'collapse': collapse}">
                    <!-- <div class="file-title">
                        <h2>文件列表</h2>
                    </div> -->

                    <ul class="file-list">
                        <li v-for="file in props.fileList" :key="file.id">
                            <uploader-file :class="'file_' + file.id" ref="files" :file="file" :list="true"></uploader-file>
                        </li>
                        <div class="no-file" v-if="!props.fileList.length"><i class="iconfont icon-empty-file"></i> 暂无待上传文件</div>
                    </ul>
                </div>
            </uploader-list>
         </div>
        </uploader>
    </div>
    </el-form>
    <span slot="footer" class="dialog-footer">
      <el-button @click="cancelAll()">取消</el-button>
      <el-button type="primary" @click="dataFormSubmit()">确定</el-button>
    </span>
  </el-dialog>
</template>

<script>
import {ACCEPT_CONFIG} from '../../../js/config';
import Bus from '../../../js/bus';
import SparkMD5 from 'spark-md5';
  export default {
    data () {
      return {
        visible: false,
        //上传成功文件集合
        fileidentifiers: [],
        statusText: {
         // success: '成功了',
        //  error: '出错了',
          uploading: '上传中',
          paused: ' ', //暂停中
          waiting: '等待中'
        },
        dataForm: {
        id:0 
        },
        options: {
                    target: "http://localhost:88/api/fileServer/uploader/chunk",
                    chunkSize: '5242880',
                    fileParameterName: 'file',
                    maxChunkRetries: 3,
                    allowDuplicateUploads: false,
                    testChunks: true,   //是否开启服务器分片校验
                    // 服务器分片校验函数，秒传及断点续传基础
                    checkChunkUploadedByResponse: function (chunk, message) {
                       // console.log("chunk",chunk);
                        console.log("messageATTT",message);
                        let objMessage = {}
                        try {
                                    objMessage = JSON.parse(message)
                                    //数据库有上传文件
                                    if (objMessage.code==1000) {
                                        return true;
                                    }
                        }catch(e){

                        }
                        
                        //根据后端返回的分片number续传 或者上传新文件
                        return (objMessage.data.uploaded || []).indexOf(chunk.offset + 1) >= 0
                    },
                    headers: {
                      //  Authorization: Ticket.get() && "Bearer " + Ticket.get().access_token
                    },
                    query() {}
                },
                attrs: {
                    accept: ACCEPT_CONFIG.getAll()
                },
                panelShow: false,   //选择文件后，展示上传panel
                collapse: false,
      }
    },
     mounted() {
            Bus.$on('openUploader', query => {
                this.params = query || {};

                if (this.$refs.uploadBtn) {
                    $('#global-uploader-btn').click();
                }
            });
        },
        computed: {
            //Uploader实例
            uploader() {
                return this.$refs.uploader.uploader;
            }
        },
    methods: {
        fileRemoved(file){
            //移除文件
        console.log("fileRemoved=",file);
         this.$http({
              url: this.$http.adornUrl(`/fileServer/uploader/deleteFileChunk`),
              method: 'post',
              data: this.$http.adornData({
                'filename': file.name,
                'identifier': file.uniqueIdentifier,
                'totalSize': file.size,
                'type': file.fileType
              })
            }).then((data) => {
            })

        },
      init (id) {
        console.log("idTTT",id);
        this.dataForm.id = id || 0
        this.visible = true
        this.$nextTick(() => {
          this.$refs['dataForm'].resetFields()
          if (this.dataForm.id) {
            this.$http({
              url: this.$http.adornUrl(`/waiguagg/info/info/${this.dataForm.id}`),
              method: 'get',
              params: this.$http.adornParams()
            }).then(({data}) => {
              if (data && data.code === 0) {
            //    this.dataForm.waiguaUsername = data.unmber.waiguaUsername
            //    this.dataForm.waiguaGrade = data.unmber.waiguaGrade
            //    this.dataForm.hatefulType = data.unmber.hatefulType
             //   this.dataForm.sealState = data.unmber.sealState
             //   this.dataForm.sealStartTime = data.unmber.sealStartTime
             //   this.dataForm.sealEndTime = data.unmber.sealEndTime
              }
            })
          }
        })
      },
      cancelAll () {
        this.visible = false;
        this.fileidentifiers = [];
        this.uploader.cancel();
        this.panelShow = false;
      },
      // 表单提交
      dataFormSubmit () {
        this.$refs['dataForm'].validate((valid) => {
          if (valid) {
            this.$http({
              url: this.$http.adornUrl(`/fileServer/uploader/updateFileInfo`),
              method: 'post',
              data: this.$http.adornData({
                'id': this.dataForm.id || undefined,
                'identifiers': this.fileidentifiers
              })
            }).then(({data}) => {
              if (data && data.code === 0) {
                this.$message({
                  message: '操作成功',
                  type: 'success',
                  duration: 1500,
                  onClose: () => {
                    this.visible = false
                    this.$emit('refreshDataList')
                    //清空文件成功列表
                    this.uploader.cancel();
                    this.panelShow = false;
                  }
                })
                 this.fileidentifiers = [];
              } else {
                this.$message.error(data.msg)
              }
            })
          }
        })
      },
      onFileAdded(file) {
                this.panelShow = true;
                this.computeMD5(file);
                Bus.$emit('fileAdded');
            },
            onFileProgress(rootFile, file, chunk) {
                console.log(`上传中 ${file.name}，chunk：${chunk.startByte / 1024 / 1024} ~ ${chunk.endByte / 1024 / 1024}`)
            },
            onFileSuccess(rootFile, file, response, chunk) {
                 let res = JSON.parse(response);

                    if (res.code==0) {
                    // 文件状态设为“合并中”
                    this.statusSet(file.id, 'merging');
                   /// this.fileComplete(file);
                   this.$http({
                        url: this.$http.adornUrl(`/fileServer/uploader/mergeFile`),
                        method: 'post',
                        data: this.$http.adornData({
                            'filename': file.name,
                            'identifier': file.uniqueIdentifier,
                            'totalSize': file.size,
                            'type': file.fileType
                        })
                        }).then((data) => {
                        console.log('data complete', data)
                        if (data && data.status === 200) {
                            this.statusRemove(file.id);
                            this.statusSet(file.id, 'fileSuccess'); 
                            console.log('上传成功1');
                            this.fileidentifiers.push(file.uniqueIdentifier);
                        }
                        })
                // 不需要合并
                } else {
                   this.statusRemove(file.id);
                   this.statusSet(file.id, 'fileSuccess'); 
                    console.log('上传成功');
                    this.fileidentifiers.push(file.uniqueIdentifier);
                }
            },
            onFileError(rootFile, file, response, chunk) {
                this.$message({
                    message: response,
                    type: 'error'
                })
            },

            /**
             * 计算md5，实现断点续传及秒传
             * @param file
             */
            computeMD5(file) {
                let fileReader = new FileReader();
                let time = new Date().getTime();
                let blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice;
                let currentChunk = 0;
                const chunkSize = 10 * 1024 * 1000;
                let chunks = Math.ceil(file.size / chunkSize);
                let spark = new SparkMD5.ArrayBuffer();

                // 文件状态设为"计算MD5"
                this.statusSet(file.id, 'md5');
                file.pause();

                loadNext();

                fileReader.onload = (e => {
                    spark.append(e.target.result);

                    if (currentChunk < chunks) {
                        currentChunk++;
                        loadNext();

                        // 实时展示MD5的计算进度
                        this.$nextTick(() => {
                            $(`.myStatus_${file.id}`).text('校验MD5 '+ ((currentChunk/chunks)*100).toFixed(0)+'%')
                        })
                    } else {
                        let md5 = spark.end();
                        this.computeMD5Success(md5, file);
                        console.log(`MD5计算完毕：${file.name} \nMD5：${md5} \n分片：${chunks} 大小:${file.size} 用时：${new Date().getTime() - time} ms`);
                    }
                });

                fileReader.onerror = function () {
                    this.error(`文件${file.name}读取出错，请检查该文件`)
                    file.cancel();
                };

                function loadNext() {
                    let start = currentChunk * chunkSize;
                    let end = ((start + chunkSize) >= file.size) ? file.size : start + chunkSize;

                    fileReader.readAsArrayBuffer(blobSlice.call(file.file, start, end));
                }
            },

            computeMD5Success(md5, file) {
                // 将自定义参数直接加载uploader实例的opts上
                Object.assign(this.uploader.opts, {
                    query: {
                        ...this.params,
                    }
                })

                file.uniqueIdentifier = md5;
                file.resume();
                this.statusRemove(file.id);
            },

            fileListShow() {
                let $list = $('#global-uploader .file-list');

                if ($list.is(':visible')) {
                    $list.slideUp();
                    this.collapse = true;
                } else {
                    $list.slideDown();
                    this.collapse = false;
                }
            },
            close() {
                this.uploader.cancel();

                this.panelShow = false;
            },

            /**
             * 新增的自定义的状态: 'md5'、'transcoding'、'failed'
             * @param id
             * @param status
             */
            statusSet(id, status) {
                console.log("status",status);
                let statusMap = {
                    md5: {
                        text: '校验MD5',
                        bgc: '#fff'
                    },
                    merging: {
                        text: '合并中',
                        bgc: '#e2eeff'
                    },
                    transcoding: {
                        text: '转码中',
                        bgc: '#e2eeff'
                    },
                    failed: {
                        text: '上传失败',
                        bgc: '#e2eeff'
                    },  
                    fileSuccess: {
                        text: '上传成功',
                        bgc: '#e2eeff'
                    }
                }

                this.$nextTick(() => {
                    $(`<p class="myStatus_${id}"></p>`).appendTo(`.file_${id} .uploader-file-status`).css({
                        'position': 'absolute',
                        'top': '0',
                        'left': '0',
                        'right': '0',
                        'bottom': '0',
                        'zIndex': '1',
                        'backgroundColor': statusMap[status].bgc
                    }).text(statusMap[status].text);
                })
            },
            statusRemove(id) {
                this.$nextTick(() => {
                    $(`.myStatus_${id}`).remove();
                })
            },

            error(msg) {
                this.$notify({
                    title: '错误',
                    message: msg,
                    type: 'error',
                    duration: 2000
                })
            }
    },
     watch: {},
        destroyed() {
            Bus.$off('openUploader');
        },
        components: {}
  }
</script>
 <style scoped lang="scss">
    #global-uploader {
     //   position: fixed;
        z-index: 20;
        right: 15px;
        bottom: 15px;

        .uploader-app {
            width: 720px;
        }

            .file-title {
                display: flex;
                height: 40px;
                line-height: 40px;
                padding: 0 15px;
                border-bottom: 1px solid #ddd;

                .operate {
                    flex: 1;
                    text-align: right;
                }
            }

            .file-list {
                position: relative;
                height: 240px;
                overflow-x: hidden;
                overflow-y: auto;
                background-color: #fff;

                > li {
                    background-color: #fff;
                }
            }

            &.collapse {
                .file-title {
                    background-color: #E7ECF2;
                }
            }

        .no-file {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            font-size: 16px;
        }

        /deep/.uploader-file-icon {
            &:before {
                content: '' !important;
            }

            &[icon=image] {
                background: url(~@/assets/img/image-icon.png);
            }
            &[icon=video] {
                background: url(~@/assets/img/video-icon.png);
            }
            &[icon=document] {
                background: url(~@/assets/img/text-icon.png);
            }
        }
    }

</style>